<!--
 * @Description: In User Settings Edit
 * @Author: your name
 * @Date: 2019-08-12 12:04:39
 * @LastEditTime: 2020-04-10 11:46:11
 * @LastEditors: Please set LastEditors
 -->
<template>
  <div @touchstart="touchStart($event)" @touchmove="touchMove($event)" @touchend="touchEnd($event)">
    <div class="pull-refresh" :style="{opacity:(this.touching||this.state>0)?1:0}" v-show="enableRefresh">
      <span class="down-tip" v-show="state==0 ">下拉更新</span>
      <span class="up-tip" v-show="state==1 ">松开刷新数据</span>
      <div class="refresh-tip" v-show="state==2">
        <img src="/images/loading.gif" width="50" height="50">
        <span class="refresh-tip">加载中…</span>
      </div>
    </div>
    <div :style="{background:'white',top:top+'px'} " id="listcontentdiv">
      <slot name="list"></slot>
    </div>
  </div>
</template>
<style scoped>
.pull-refresh {
  background: #eeeeee;
  position: absolute;
  height: 50%;
  width: 100%;
  text-align: center;
  padding-top: 30px;
}
.refresh-tip {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
}
</style>
<script>
import bus from '@/common/bus'
import { apiConstants } from '@/js/utils';
import { isBottom } from '@/js/utils'
export default {
  props: {
    api: {
      type: Object,
      required: true
    },
    params: {
      type: Object,
      default() {
        return {}
      }
    },
    //设置显示的top ，如果top为 0 ，则显示  查看更多，下拉刷新，大于0则不显示
    showTop: {
      type: Number,
      default: 0
    },
    event: {  // 请求到数据事件名
      type: String,
      default: 'more'
    },
    resList: {  // 请求返回值的 list 名字
      type: String,
      default: ''
    },
    enableRefresh: {//是否支持下拉刷新
      type: Boolean,
      required: false
    },
    isExecution:{ //是否需要一开始加载
      type: Boolean,
      required: true
    },
    contentViewHeight:{//滚动区域可是高度
      type:Number,
      default:null
    },
    contentArea:{//滚动区域元素选择器
      type:String,
      default:null
    },
    validEvent:{
      type:String,
      default:null
    }

  },
  data() {
    return {
      offset: 100,
      state: 0,//0表示滑动距离不足触发刷新，1表示滑动距离可以触发刷新，等待松手后刷新，2表示正在刷新数据
      pageNo: 1,
      ctrl: false, // 不可请求为 true
      top: 0,
      touching: false,
      loading: false
    }
  },
  watch: {
    touching() {
      if (this.touching) {
        document.getElementById("listcontentdiv").style.minHeight = document.getElementsByClassName("pull-refresh")[0].offsetHeight + "px";
      } else if (this.state == 0) {
        document.getElementById("listcontentdiv").style.minHeight = "";
      }
    },
    state() {
      if (this.state == 0) {
        document.getElementById("listcontentdiv").style.minHeight = "";
      }
    },
  },
  created() {
    if(this.isExecution){
      this.$Toast.start();
      this.$LoadingBar.finish();
      this.requestData(this.initCallback);
    }

  },
  mounted() {
    // 初始化列表滚动请求更多事件
    bus.$on('requestData', (aa)=>{this.clearPageNo();this.requestData(this.initCallback);})
    if(this.contentArea){
      $(this.contentArea).on('scroll',this.moreData);
    }else{
      document.addEventListener('scroll', this.moreData, false)
    }
  },
  beforeDestroy() {
    if(this.contentArea){
      $(this.contentArea).off('scroll', this.moreData);
    }else{
      document.removeEventListener('scroll', this.moreData)
    }
    bus.$off('requestData')
  },
  methods: {
    clearPageNo(){
      this.pageNo = 1;
      this.ctrl = false;
      // console.log("来了来了来了");
    },
    requestData(cb) {
      console.log("requestData 走起来")
      // 测试用
      if (!this.api) {
        setTimeout(() => {
          bus.$emit(this.event, new Array(10))
          this.$Toast.finish()
        }, 100)
        return
      }
      if (this.pageNo == 0) {
        this.pageNo = 1;
        bus.$emit("clearlist");
      }
      this.params.pageNo = this.pageNo
      this.getData(cb);
    },
    getData(cb) {
      if (!this.loading){
        let _this= this;
        this.loading = true;
        Vue.prototype.$ajax(this.api, {
          data: this.params,
          isJson: this.api.method.toLowerCase() == "get",
          success: res => {
            //console.log(_this.state+"---------------")
            if (_this.state === 2) {//如果是下拉刷新，需要先发清空list的通知K
              bus.$emit("clearlist");
            }
            //返回回调 moreData 方法
            bus.$emit(_this.event, res || null);
            this.loading = false;
            this.resList ? cb(res[_this.resList]) : cb(res)  // 提示是否有更多数据
            // if(res.length==0){
            //   this.$LoadingBar.finish()
            // }
          },
          error: res => {
            this.loading = false;
            this.$LoadingBar.error();
          },
          fail: res => {
            this.$LoadingBar.error();
            this.loading = false;
          },
          closeToast: true
        })
      }

    },
    // 滚动到底部请求更多
    moreData() {
      if(this.validEvent && this.validEvent != this.event){
        return
      }
      if (this.pageNo == 1) {
        //清空数据
        bus.$emit("clearlist");
      }
      if (this.isBottom()) {
        if (this.ctrl || this.state === 2 || this.showTop > 0 || this.loading) return
        this.ctrl = true
        this.$LoadingBar.start()
        this.requestData(this.moreCallback)
      }
      if (this.enableRefresh && !this.touching) {
        //TODO:手机端用力划一下，一直滚动，会出现滚动到顶部以上的情况，如果这个时候需要触发下拉刷新，则在这里加代码
        //如果window.scrollY小于0，就可以写下拉刷新的逻辑
      }
    },
    isBottom(){
      let element;
      let scrollHeight = null;
      let scrollTop = null;
      if(this.contentArea){
        element = $(this.contentArea);
        scrollHeight = element?element[0].scrollHeight:null;
        scrollTop = element?element[0].scrollTop:null;
      }
      return isBottom(this.contentViewHeight,scrollHeight,scrollTop);
    },

    // 初始化列表回调
    initCallback(res) {
      this.pageNo++
      this.$Toast.finish();


    },

    // 更多列表回调
    moreCallback(data) {
      if (data.listInfo != undefined) {
        data = data.listInfo;
      }
      if ((!data && this.pageNo!=1) || (!data.length && this.pageNo!=1)) {  // 没有数据了
        this.$LoadingBar.end()
        return
      }
      this.ctrl = false  // 只有后面有数据才可请求下一页
      this.pageNo++
      this.$LoadingBar.finish()
    },

    touchStart(e) {
      this.startY = e.targetTouches[0].pageY;
      this.startScroll = window.scrollY || 0;
      this.touching = true; //留着有用，不能删除
    },
    touchMove(e) {
      console.log(2222222222222)
      if (!this.enableRefresh || !this.touching) {
        return
      }
      let diff = e.targetTouches[0].pageY - this.startY - this.startScroll
      if (diff > 0) e.preventDefault()
      this.top = Math.pow(diff, 0.8) + (this.state === 2 ? this.offset : 0)
      if (this.state === 2) { // in refreshing
        return
      }
      if (this.top >= this.offset) {
        this.state = 1;
      } else {
        this.state = 0
      }
    },
    touchEnd(e) {
      if (!this.enableRefresh) {
        return
      }
      if (this.state === 2) { // 正在刷新，只是将滑动位置调整，不再触发刷新函数
        this.state = 2
        this.top = this.offset
        return
      }
      if (this.state === 1) { // 已经达到触发刷新的滑动距离，将状态变为刷新中，然后触发刷新函数
        console.log("this.state",this.state)
        this.refresh()
      } else { // 没达到距离，取消刷新
        this.state = 0
        this.top = 0
      }
      this.touching = false

    },
    refresh() {
      this.state = 2;
      this.top = this.offset;
      this.pageNo = 1;
      setTimeout(() => {
        this.requestData(this.refreshDone)
      }, 300);
    },
    refreshDone() {
      this.initCallback();
      this.state = 0;
      this.top = 0;
      this.$LoadingBar.finish();
      this.ctrl = false;
    }
  }
}
</script>

